var BENCODE = require('./bencode.js');
var createHash = require('crypto').createHash;
var fs = require('fs');
var utils = require('./utils.js');

var torrent = {
	announce: 'url/to/tracker',
	info: {
		name: 'directory',
		"piece length": 124561,
		pieces: '',
		length: 123456,
		files: [
			{
				length: 145654,
				path: [
					'asd',
					'dfg'
				]
			}
		]
	}
};

function createTorrentFromPath(path, pieceLength, callback) {
	if (typeof pieceLength == 'undefined') {
		return;
	}
	if (typeof pieceLength == 'function') {
		callback = pieceLength;
		pieceLength = 4 * 1024 * 1024;
	}
	var torrent = new Torrent();
	utils.readDirTree(path, function(err, dirTree) {
		if (err) return callback(err);
		var fileList = utils.dirTreeToFileList(dirTree);
		var files = [];
		var pieces = '';
		
		var pieceHash = createHash('sha1');
		var index = 0;
		
		(function next(fileIndex) {
			if (fileIndex == fileList.length) {
				pieces += pieceHash.digest();
				torrent.info.pieces = pieces;
				torrent.info.files = files;
				torrent.info['piece length'] = pieceLength;
				torrent.info.name = path.substr(path.lastIndexOf('/') + 1).replace(' ', '.');
				return callback(null, torrent);
			}
			var fileParts = fileList[fileIndex];
			var fileName = path + '/' + fileParts.join('/');
			fs.stat(fileName, function(err, stats) {
				if (err) return callback(err);
				files.push({
					length: stats.size,
					path: fileParts
				});
				var read = fs.createReadStream(fileName, {
					bufferSize: pieceLength
				});
				read.on('data', function(chunk) {
					if (chunk.length + index > pieceLength) {
						pieceHash.update(chunk.slice(0, pieceLength - index));
						pieces += pieceHash.digest();
						pieceHash = createHash('sha1');
						pieceHash.update(chunk.slice(pieceLength - index));
						index = (index + chunk.length) % pieceLength;
					} else {
						pieceHash.update(chunk);
						index += chunk.length;
					}
				});
				read.on('end', function() {
					next(fileIndex + 1);
				});
			});
		})(0);
	});
};

function Torrent() {
	this.announce = null;
	this.info = {
		'piece length': null,
		name: null,
		pieces: null,
		files: null
	};
}

Torrent.prototype.getInfoHash = function() {
	var infoHash = createHash('sha1');
	infoHash.update(BENCODE.stringify(this.info));
	return infoHash.digest();
};

Torrent.prototype.toString = function() {
	return BENCODE.stringify({
		announce: this.announce,
		info: this.info
	});
};

Torrent.prototype.saveToFile = function(filename, callback) {
	fs.writeFile(filename, this.toString(), 'binary', callback);
};

module.exports = {
	Torrent: Torrent,
	createTorrentFromPath: createTorrentFromPath
};